package com.aididi.designpatter;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @Auther: zx.xu
 * @Description:    基于cglib的动态代理
 * Cglib代理,也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能的扩展.
 * JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口,如果想代理没有实现接口的类,就可以使用Cglib实现.
 * Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接口.它广泛的被许多AOP的框架使用,例如Spring AOP和synaop,为他们提供方法的interception(拦截)
Cglib包的底层是通过使用一个小而块的字节码处理框架ASM来转换字节码并生成新的类.不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉.
 */
public class CglibDynamicProxyDemo {

    public static void main(String[] args) {
        PersonDao target = new PersonDao();
        ProxyFactory proxyFactory = new ProxyFactory(target);
        PersonDao proxy = (PersonDao)proxyFactory.getProxyInstance();
        proxy.update("返回对象");
    }

}

//目标对象类:PersonDao.java
class PersonDao {

    public String update(String name) {
        // TODO Auto-generated method stub
        System.out.println("修改个人信息");
        return name;
    }
}

//Cglib代理工厂
class ProxyFactory implements MethodInterceptor {

    private Object target;
    public ProxyFactory(Object target){
        this.target = target;

    }

    //给目标对象创建一个代理对象
    public Object getProxyInstance(){
        //工具类
        Enhancer en = new Enhancer();
        //设置父类
        en.setSuperclass(target.getClass());
        //设置回调函数,this代表当前类ProxyFactory
        en.setCallback(this);
        //创建子类代理对象
        return en.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("开始事务...");
        Object returnValue = method.invoke(target, objects);
        System.out.println("拦截对象："+returnValue);
        System.out.println("提交事务...");
        return returnValue;
    }
}